import {
  Body,
  Controller,
  Post,
  Get,
  Session,
  Headers,
  UseInterceptors,
  UploadedFile,
} from '@nestjs/common';
import {
  ApiBearerAuth,
  ApiConsumes,
  ApiOperation,
  ApiResponse,
  ApiTags,
} from '@nestjs/swagger';
import { FileInterceptor } from '@nestjs/platform-express';
import { createWriteStream } from 'fs';
import { join } from 'path';
import * as svgCaptcha from 'svg-captcha';
import { compare } from 'bcryptjs';
import { IResponseData, responseData } from 'src/utils/result';
import { UserDto } from '../user/user.dto';
import { UserService } from '../user/user.service';
import { LoginDto, UploadDto } from './common.dto';
import { CommonService } from './common.service';
import { mkdirsSync } from 'src/utils/tools';

@ApiTags('基础模块')
@ApiBearerAuth()
@Controller()
export class CommonController {
  constructor(
    private readonly userService: UserService,
    private readonly commonService: CommonService,
  ) {}

  @ApiOperation({ summary: '用户登录' })
  @ApiResponse({
    status: 200,
    description: '用户登录',
  })
  @Post('login')
  async login(
    @Body() dto: LoginDto,
    @Session() session: Record<string, any>,
    @Headers() headers,
  ): Promise<IResponseData> {
    // 判断验证码
    if (!session.captcha) throw new Error('请获取验证码');
    if (
      dto.captcha.toLocaleLowerCase() !==
      (session.captcha as string).toLocaleLowerCase()
    )
      throw new Error('验证码错误');

    const user: UserDto = await this.userService.getOne({
      where: {
        user_name: dto.user_name,
      },
      relations: ['roles'],
    });
    // 判断用户是否存在
    if (!user) throw new Error('不存在该用户');
    // 校验密码是否正确
    const checkPassword = await compare(dto.password, user.password);
    if (!checkPassword) throw new Error('密码错误');
    if (user.status === '0') throw new Error('该用户已被停用');
    if (user.is_delete === '1') throw new Error('该用户已被删除');
    // 调用成功后清除session中的验证码
    session.captcha = null;
    const payload = { id: user.id, user_name: user.user_name };
    const data = this.commonService.getToken(payload);

    return responseData({ code: 10000, data, language: headers['language'] });
  }

  @ApiOperation({ summary: '退出系统' })
  @ApiResponse({
    status: 200,
    description: '退出系统',
  })
  @Post('logout')
  async logout(
    @Session() session: Record<string, any>,
    @Headers() headers,
  ): Promise<IResponseData> {
    session.userInfo = null;
    return responseData({ code: 10001, language: headers['language'] });
  }

  @ApiOperation({ summary: '获取验证码' })
  @ApiResponse({
    status: 200,
    description: '获取验证码',
  })
  @Get('captcha')
  async captcha(@Session() session: Record<string, any>): Promise<any> {
    const captcha = svgCaptcha.create({
      size: 4,
      fontSize: 50,
      width: 160,
      height: 50,
      ignoreChars: '0oO1ilI', // 验证码字符中排除 0o1i
      noise: 3, // 干扰线条的数量
      // color: true, // 验证码的字符是否有颜色，默认没有，如果设定了背景，则默认有
      // background: '#cc9966',
    });
    session.captcha = captcha.text;
    return captcha.data;
  }

  @ApiOperation({ summary: '上传文件' })
  @ApiResponse({
    status: 200,
    description: '上传文件',
  })
  @UseInterceptors(FileInterceptor('file'))
  @ApiConsumes('multipart/form-data')
  @Post('upload')
  uploadFile(
    @UploadedFile() file: Express.Multer.File,
    @Body() body: UploadDto,
    @Session() session,
  ) {
    if (!file) {
      throw new Error('请选择上传文件');
    }
    console.log(body);
    const dir = join(
      __dirname,
      '../../../../',
      'upload/' + session.userInfo.id,
    ); // 目录名
    const filename =
      file.originalname.substring(0, file.originalname.lastIndexOf('.')) +
      '.' +
      new Date().getTime(); // 文件名
    const suffix = file.originalname.substring(
      file.originalname.lastIndexOf('.'),
    ); // 后缀

    // 没有则递归创建文件夹
    mkdirsSync(dir);
    const writeFile = createWriteStream(join(dir, filename + suffix));
    writeFile.write(file.buffer);

    return responseData({
      data: { path: `/upload/${session.userInfo.id}/${filename + suffix}` },
    });
  }
}
